package persistencia;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import javax.jdo.Extent;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;
import javax.jdo.Transaction;

/**
 * 
 * 
 * Clase que generaliza el almacenamiento de los datos en la base de datos
 * utilizada. Todos los metodos que involucren presistencia propiamente
 * hablando, estaran en esta clase.
 * 
 * @version 1.0 --- 2011
 * 
 * @see java.util.Collection;
 * @see java.util.Iterator;
 * @see java.util.Vector;
 * @see javax.jdo.Extent;
 * @see javax.jdo.PersistenceManager;
 * @see javax.jdo.PersistenceManagerFactory;
 * @see javax.jdo.Query;
 * @see javax.jdo.Transaction;
 * 
 */
public class Persistencia {

	private PersistenceManagerFactory pmf = null;
	private PersistenceManager pm = null;
	private Transaction tx = null;

	/**
	 * 
	 */
	public Persistencia() {
		pmf = ConexionDB.getConexion();

		pm = pmf.getPersistenceManager();
		tx = pm.currentTransaction();
		tx.begin();
		System.out.println("TRANSACCION ABIERTA");
	}

	/**
	 * @param clase
	 * @param filtro
	 * @return
	 * @throws Exception
	 */
	public Object getObjeto(Class clase, String filtro) throws Exception {
		Object obj = null;
		try {
			Extent e = pm.getExtent(clase, true);
			Query q = pm.newQuery(e, filtro);
			Collection objs = (Collection) q.execute();
			Object[] objects = objs.toArray();
			if (objects.length > 0)
				obj = objects[0];
		} catch (Exception ex) {
			ex.printStackTrace();
			throw ex;
		}
		return obj;
	}

	/**
	 * @param clase
	 * @return
	 * @throws Exception
	 */
	public Vector getObjetos(Class clase) throws Exception {
		return getObjetos(clase, "");
	}

	/**
	 * @param clase
	 * @param filtro
	 * @return
	 * @throws Exception
	 */
	public Vector getObjetos(Class clase, String filtro) throws Exception {
		Vector vector = new Vector();
		try {
			Extent ext = pm.getExtent(clase, true);
			Query query = pm.newQuery(ext, filtro);
			Collection c = (Collection) query.execute();
			Object p = null;
			Iterator iter = c.iterator();
			while (iter.hasNext()) {
				p = (Object) iter.next();
				vector.add(p);
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw (e);
		}
		return vector;
	}

	/**
	 * @param obj
	 * @throws Exception
	 */
	public void guardarObjeto(Object obj) throws Exception {
		try {
			System.out.println("Make " + obj);
			pm.makePersistent(obj);
		} catch (Exception ex) {
			ex.printStackTrace();
			throw (ex);
		}
	}

	/**
	 * @param objetos
	 * @param todos
	 * @throws Exception
	 */
	public void guardarObjetos(Object objetos[], boolean todos)
			throws Exception {
		int nObjs = objetos.length;
		if (todos) {
			try {
				for (int i = 0; i < nObjs; i++)
					pm.makePersistent(objetos[i]);
			} catch (Exception ex) {
				ex.printStackTrace();
				throw (ex);
			}
		} else {
			for (int i = 0; i < nObjs; i++) {
				try {
					pm.makePersistent(objetos[i]);
				} catch (Exception ex) {
					ex.printStackTrace();
					throw (ex);
				}
			}
		}
	}

	/**
	 * @param obj
	 * @throws Exception
	 */
	public void borrarObjeto(Object obj) throws Exception {
		try {
			pm.deletePersistent(obj);
		} catch (Exception ex) {
			ex.printStackTrace();
			throw (ex);
		}
	}

	/**
	 * @param objetos
	 * @throws Exception
	 */
	public void borrarObjetos(Object objetos[]) throws Exception {
		int nObjs = objetos.length;
		try {
			for (int i = 0; i < nObjs; i++)
				pm.deletePersistent(objetos[i]);
		} catch (Exception ex) {
			ex.printStackTrace();
			throw (ex);
		}
	}

	/**
	 * 
	 */
	public void cerrarTransaccion() {
		tx.commit();
		System.out.println("TRANSACCION CERRADA");
	}

	/**
	 * 
	 */
	public void cerrarPersistencia() {
		if (!pm.isClosed())
			pm.close();
	}

	/**
	 * 
	 */
	public void realizaRollback() {
		if (this.tx.isActive()) {
			this.tx.rollback();
			System.out.println("ROLLBACK EJECUTADO");
		}
	}
}